Release 10.1A: OpenEdge Development:
Progress 4GL Reference
DEFINE PARAMETER statement
Defines a run-time parameter in a Progress subprocedure, Windows dynamic link library (DLL) routine, UNIX shared library routine, or ActiveX control event procedure.
Note: To define run-time parameters of a user-defined function, or a method within a class (including constructor methods), see the Parameter definition syntax reference entry in this book.Each parameter requires its own DEFINE statement. The parameters must be specified in the RUN statement in the same order they are defined with DEFINE statements. In addition, the parameter types (INPUT, OUTPUT, INPUT-OUTPUT, RETURN, TABLE, TABLE-HANDLE, DATASET, DATASET-HANDLE, and BUFFER) specified in the DEFINE and RUN statements must agree. The corresponding data types and run-time values must also be compatible enough to allow Progress to perform any necessary conversions.
Syntax
INPUT PARAMETERDefines a parameter that gets its value from one of the following sources:
- If the calling procedure runs the current (called) procedure synchronously, the value comes from the corresponding INPUT parameter of the RUN statement.
- If the current procedure is the event procedure specified to handle the PROCEDURE-COMPLETE event for an asynchronous remote procedure, the value comes from the corresponding OUTPUT or INPUT-OUTPUT parameter of the remote procedure.
OUTPUT PARAMETERDefines a parameter that returns a value to one of the following destinations:
- If the calling procedure runs the current (called) procedure synchronously, the value is returned to the corresponding OUTPUT parameter of the RUN statement in the calling procedure.
- If the calling procedure runs the current (called) procedure as an asynchronous remote procedure, the value is returned to the corresponding INPUT parameter of the event procedure specified to handle the PROCEDURE COMPLETE event for the current procedure.
INPUT-OUTPUT PARAMETERDefines a parameter that receives an initial value passed from the calling procedure that can be subsequently modified by the called procedure. The calling procedure cannot pass a literal value. The called procedure returns the modified value to one of the following destinations:
- If the calling procedure runs the current (called) procedure synchronously, the value is returned to the corresponding INPUT-OUTPUT parameter of the RUN statement in the calling procedure.
- If the calling procedure runs the current (called) procedure as an asynchronous remote procedure, the value is returned to the corresponding INPUT parameter of the event procedure specified to handle the PROCEDURE COMPLETE event for the current procedure.
RETURN PARAMETERDefines a parameter that holds the return value of a DLL or UNIX shared library routine. When the DLL routine returns, the value of this parameter is passed back to the calling procedure. You can only have one RETURN parameter per routine.
parameterIdentifies the name of the parameter you want to define.
AS [ HANDLE TO ]datatypeSpecifies the data type of the parameter.
For Progress subprocedures,
datatypecan specify any built-in Progress data type used to define variables. For more information, see the reference entry for the DEFINE VARIABLE statement.For DLL or UNIX shared library routines,
datatypecan specify a Progress DLL data type. Progress DLL data types include the built-in Progress data types CHARACTER and MEMPTR, Windows DLL-equivalent data types, and UNIX shared library data types.Table 26 shows how Windows DLL and UNIX shared library data types map to Progress DLL data types.
Caution: For
Table 26: Data types for DLL and UNIX shared library routine parameters Example Cdata type Progress DLL parameterdata type Windows DLL and UNIX shared library data type 8-bit unsigned integer 16-bit signed integer 16-bit unsigned integer long, int1 LONG2 32-bit signed integer 4-byte floating point 8-byte floating point Address (usually 32 bits)c-data-type3 HANDLE TOparameter-data-type3 Address (usually 32 bits)char*,output-pointer(which can bechar**,short**, and so on), or a pointer to a structure. Address (usually 32 bits)
- The C data type
intgenerally specifies a size that depends on the operating system.- To pass a NULL pointer value to a DLL routine, pass 0 using a
LONGparameter. Do not use a nullMEMPTRvariable to pass a NULL value. However, you can pass a NULL value in one or more elements of aMEMPTRarray. If this conflicts with another way to call the DLL routine, specify a second declaration for the same routine using theORDINALoption of thePROCEDUREstatement.- You can use the
HANDLETOoption to specify a pointer to a scalar type. Therefore, you can use theHANDLETOoption with the parameter data types (that is,BYTE,SHORT,UNSIGNED-SHORT,LONG,FLOAT, andDOUBLE) in order to specify a pointer to the respective C data types (that is, char, short, unsigned short, long, int, float, and double). For aCHARACTERorMEMPTRparameter, it is redundant because this data type is always passed using a pointer (char*).CHARACTERparameters, Progress always passes the routine a pointer to the character or character string value rather than the value itself. If the routine modifies the value, it can also modify Progress memory outside the bounds of theCHARACTERvalue with unpredictable results. For this reason, Progress does not allow you to useOUTPUTorRETURNforCHARACTERorLONGCHARparameters, as well asCHARACTERor LONGCHAR array parameters, and does not recommend you useINPUT-OUTPUTforCHARACTERorLONGCHARparameters. Rather, pass the character string as aMEMPTRparameter. For more information, see OpenEdge Development: Programming Interfaces . Note: You cannot useRETURNfor any type of array parameter.To indicate that the DLL or UNIX shared library parameter is a pointer to a value rather than the value itself, use the HANDLE option. The HANDLE option is required when the DLL routine expects a pointer to the value. Note that the CHARACTER data type implies the HANDLE option, whether or not you specify it. The TO keyword aids readability but has no meaning.
For ActiveX control event procedures,
datatypecan specify the built-in Progress data type that maps to the COM object data type of an ActiveX event parameter. Table 27 shows how the COM object data types for event parameters (shown as ActiveX data types) map to Progress data types.
Table 27: Data types for ActiveX control event procedures ActiveX data type1 Progress data type Array Progress array variable Array of bytes RAW Boolean (2-byte integer) LOGICAL Byte (unsigned byte) INTEGER Currency (8-byte integer with fixed decimal point) DECIMAL DateDouble DATEDATETIMEDATETIME-TZ Decimal DECIMAL Double (8-byte floating point) DECIMAL Error Code INTEGER Integer (2-byte integer) INTEGER Long (4-byte integer) INTEGER Object (32-bit value) COM-HANDLE String (character string type) CHARACTERLONGCHAR Unsigned Byte INTEGER Unsigned Long (4-byte integer) INTEGER Unsigned Short (2-byte integer) INTEGER Variant (variable type) <ANYTYPE>2
- For more information on these data type implementations for COM objects, see OpenEdge Development: Programming Interfaces .
- For Variant event parameters, the AppBuilder specifies <ANYTYPE> as a place holder. You must change <ANYTYPE> to the data type that most closely matches the expected value. For more information, see the available documentation on the event parameter.
AS [ CLASS ] {type-name}Defines a class or interface parameter. Progress passes the object reference for a class or interface parameter (by value), not the class or interface itself.
type-nameA character string that specifies the type name of a class or interface. Specify a type name using the
package.class-namesyntax as described in the Type-name syntax reference entry in this book.If the specified class or interface type name conflicts with an abbreviation of a built-in Progress data type name, such as INT for INTEGER, you must specify the CLASS keyword.
LIKE, CASE SENSITIVE, FORMAT, DECIMALS, INITIAL, COLUMN-LABEL, LABEL, NO-UNDOFor descriptions of these options, see the DEFINE VARIABLE statement reference entry.
EXTENT [expression]Defines a determinate array parameter (which has a defined number of elements) or an indeterminate array parameter (which has an undefined number of elements). To define a determinate array parameter, specify the EXTENT option with the
expressionargument. This optional argument evaluates to an integer value that represents an extent for the array parameter. To define an indeterminate array parameter, specify the EXTENT option without theexpressionargument. Progress determines the size of indeterminate array parameters at runtime.You can pass a determinate array or indeterminate array to a procedure or function that declares the parameter as an indeterminate array. You cannot pass an indeterminate array to a procedure or function that declares the parameter as a determinate array. If you call a procedure or function that fixes the number of elements in an indeterminate array, Progress treats the fixed indeterminate array as a determinate array.
You cannot pass an indeterminate array to a COM object, DLL routine, or UNIX shared library routine.
If you want to define a parameter that is like an array variable or field, using the LIKE option, but you do not want the parameter to be an array, you can use EXTENT 0 to indicate a non-array parameter.
If you are using the AS
datatypeoption and you do not use the EXTENT option (or you specifyexpressionas 0), the parameter is not an array parameter. If you are using the LIKEfieldoption and you do not use the EXTENT option, the parameter uses the extent defined for the database field you name (if any).PARAMETER BUFFERbufferFORtable[ PRESELECT ] [ LABELlabel]Defines a buffer parameter. You can pass a buffer associated with a database table to a buffer parameter. You cannot pass a work table to a buffer parameter. A buffer parameter is always INPUT-OUTPUT. You cannot pass buffer parameters to the AppServer.
For descriptions of the PRESELECT and LABEL options, see the DEFINE BUFFER statement reference entry.
TABLE FORtemp-table-nameDefines a temporary table parameter.
You can pass a temporary table parameter to both local and remote procedures. Progress passes the parameter by value, by default. That is, the calling routine and the called routine each have their own instance of the temporary table. When you invoke the RUN statement, Progress deep-copies the temporary table from one routine’s instance to the other routine’s instance. Which table travels depends on whether the parameter is INPUT, OUTPUT, or INPUT-OUTPUT. When you pass a temporary table as an INPUT parameter, Progress overlays the stationary instance with the traveling table, by default. You can also append the traveling table to the end of the stationary instance by specifying the APPEND option. For more information about the APPEND option, see the option description below.
When passing a temporary table parameter to a local procedure, you can override the default by passing the parameter by reference or by binding (that is, by specifying the parameter in a RUN statement using either the BY-REFERENCE or BIND option). Passing a temporary table parameter by reference or by binding allows the calling routine and the called routine to access the same object instance (instead of deep-copying the parameter).
Note: When you specify the BIND option in the DEFINE PARAMETER statement, you must also specify the BIND option in the RUN statement.For more information about passing a temporary table parameter by reference or by binding, see the Parameter passing syntax reference entry in this book. For more information about temporary table parameters, see OpenEdge Development: Progress 4GL Handbook .
TABLE-HANDLEtemp-table-handleDefines a temporary table handle parameter.
DATASETdataset-nameDefines a static ProDataSet object parameter.
You can pass a ProDataSet object parameter to both local and remote procedures. Progress passes the parameter by value, by default. That is, the calling routine and the called routine each have their own instance of the object. When you invoke the RUN statement, Progress deep-copies the object from one routine’s instance to the other routine’s instance. Which object travels depends on whether the parameter is INPUT, OUTPUT, or INPUT-OUTPUT. When you pass a ProDataSet object as an INPUT parameter, Progress overlays the stationary instance with the traveling ProDataSet object, by default. You can also append the traveling ProDataSet object to the end of the stationary instance by specifying the APPEND option. For more information about the APPEND option, see the option description below.
When passing a ProDataSet object parameter to a local procedure, you can override the default by passing the parameter by reference or by binding (that is, by specifying the parameter in a RUN statement using either the BY-REFERENCE or BIND option). Passing a ProDataSet object parameter by reference or by binding allows the calling routine and the called routine to access the same object instance (instead of deep-copying the parameter).
Note: When you specify the BIND option in the DEFINE PARAMETER statement, you must also specify the BIND option in the RUN statement.For more information about passing a ProDataSet object parameter by reference or by binding, see the Parameter passing syntax reference entry in this book. For more information on ProDataSet object parameters, see OpenEdge Development: Progress 4GL Handbook .
DATASET-HANDLEdataset-handleDefines a ProDataSet object handle parameter.
FOR ... APPENDSpecifies whether or not to append the traveling temporary table data to the stationary temporary table instance. To append input parameter data, specify the APPEND option in the DEFINE PARAMETER statement. To append output parameter data, specify the APPEND option in the RUN statement.
For
temp-table-name, FOR is required and APPEND is optional.For
temp-table-handle, both FOR and APPEND are optional and are used together. Without the FOR keyword, the temporary table handle is local to the called procedure - it is created when the procedure starts and deleted when the procedure completes. Therefore, there is nothing to APPEND the received parameter to. When the FOR keyword is used, the temporary table handle is defined at a higher level outside the called procedure and continues to exist after the called procedure completes.BINDIndicates that a TABLE, TABLE-HANDLE, DATASET, or DATASET-HANDLE parameter binds a reference-only object in one routine to an object instance defined and instantiated in another local routine.
When you define a reference-only object in the calling routine, and you want to bind that object definition to an object instance in the called routine, define the parameter by specifying the BIND option in an INPUT or INPUT-OUTPUT parameter definition. When you define a reference-only object in the called routine, and you want to bind that object definition to an object instance in the calling routine, define the parameter by specifying the BIND option in an OUTPUT parameter definition. In either case, the reference-only object definition remains bound to the object instance until the routine containing the reference-only object definition is deleted or terminates.
Caution: Do not delete the object or routine to which a reference-only object is bound, or you might be left with references to an object that no longer exists.You can bind multiple reference-only object definitions to the same object instance. You can also bind a single reference-only object definition to the same object instance multiple times without generating an error. However, you cannot bind a single reference-only object definition to multiple object instances.
When passing one of these parameters to a remote procedure, Progress ignores the BIND option and deep-copies the parameter based on the specified parameter mode.
For more information about passing these parameters by binding, see the Parameter passing syntax reference entry in this book.
ExamplesIn the following examples, the
r-runpar.pprocedure runs a subprocedure calledr-param.pand passes the subprocedure an INPUT parameter. The subprocedurer-param.pdisplays the INPUT parameter.
In the following example, the
r-runpr1.pprocedure runs a subprocedure calledr-param1.p. This example illustrates the use of multiple parameters and shows that the parameters must be passed in the proper order and must be of the same data type. Note that if you do not specify a parameter type in the RUN statement, Progress assumes it is an input parameter.
In the following example, the
r-runpr2.pprocedure displays information from a database table and assigns the value of a database field to a variable called io-param. The variable is passed as an INPUT-OUTPUT parameter to a subprocedure calledr-param2.p. The subprocedurer-param2.pperforms a calculation on the INPUT-OUTPUT parameter, then passes it back to the main procedure. Ther-runpr2.passigns the value io-param to a database field, then displays io-param.
The following example uses a buffer parameter. The procedure
r-bufp.ppasses the Customer buffer tor-fincus.p. Ther-fincus.pprocedure then attempts to find a record using that buffer.
The following example defines parameters for the DLL routine,
MessageBox(), which displays a message on the screen:
Notes
- All procedure parameters are normally passed by value, by default. This means that for any INPUT-OUTPUT or OUTPUT parameter, the field or variable that receives the output value is not set by the called procedure until the procedure returns without error. An exception is made for local DATASET, DATASET-HANDLE, TABLE, and TABLE-HANDLE parameters, which you may pass by reference or by binding by specifying the parameter in a RUN statement using either the BY-REFERENCE or BIND option. If you specify the BIND option in the RUN statement, you must also specify the BIND option in the DEFINE PARAMETER statement.
For more information about passing parameters by reference or by binding, see the Parameter passing syntax reference entry in this book. For more information about passing parameters to both local and remote procedures, see OpenEdge Development: Progress 4GL Handbook .
- You cannot pass a BLOB or CLOB field as a parameter. To pass a BLOB or CLOB field as a parameter, you must include the field in a temp-table or convert the field to its MEMPTR or LONGCHAR counterpart, respectively.
- Buffer parameters are scoped in the same way as shared buffers. They also affect cursors defined in the calling procedure in the same way as shared buffers.
- For DLL or UNIX shared library routine declarations:
- You cannot pass a DATE, DATETIME, or DATETIME-TZ as a parameter to or from a DLL routine or a UNIX shared library routine.
- You can pass a LONGCHAR as a parameter to a DLL routine or a UNIX shared library routine. When passing a LONGCHAR parameter, Progress passes only the text string (not the code page information). You are responsible for setting the code page of a LONGCHAR parameter.
- You can pass an array of type INTEGER or DECIMAL as a parameter to or from a DLL routine or a UNIX shared library routine. You can pass an array of type CHARACTER to (not from) a DLL routine or a UNIX shared library routine.
- You cannot pass a variable or array that contains the Unknown value (
?) to a DLL.- RETURN parameters are supported only for DLL or UNIX shared library routines. The RETURN parameter type must match the OUTPUT parameter that returns the DLL function value in the RUN statement for the routine. You cannot pass an array as a RETURN parameter to DLL or UNIX shared library routines. Use a MEMPTR instead.
- If you specify a RETURN parameter as MEMPTR to return a character string, use the GET-STRING function to extract the CHARACTER value.
- For more information on DLL routine parameters and how they map to Progress data types, see the chapter on DLLs in OpenEdge Development: Programming Interfaces .
- You cannot pass a MEMPTR as a parameter to or from a COM object.
- You can pass a LONGCHAR, a DATETIME, a DATETIME-TZ, and an array as a parameter to or from a COM object.
When passing a LONGCHAR parameter to a COM object, Progress passes only the text string (not the code page information). When receiving a text string from a COM object into a LONGCHAR parameter, Progress converts the text string to the code page associated with the LONGCHAR parameter only if the LONGCHAR has a fixed code page. Otherwise, Progress sets the LONGCHAR code page to UTF-16. If Progress cannot convert a LONGCHAR, it raises a runtime error.
When passing a DATETIME or DATETIME-TZ parameter to a COM object, Progress represents the time to the millisecond. When passing a DATETIME-TZ parameter to a COM object, Progress first converts the DATETIME-TZ value relative to the local session's date and time, and then drops the time zone.
When receiving a date from a COM object into a DATETIME or DATETIME-TZ parameter, Progress represents the time to the millisecond. When receiving a date from a COM object into a DATETIME-TZ parameter, Progress sets the time zone to the local session's time zone.
- For more information on ActiveX event parameters, or using COM objects in the 4GL, see the chapter in OpenEdge Development: Programming Interfaces .
- For dynamic temp-table parameters:
- If the parameter is INPUT TABLE-HANDLE, the temp-table definition behind the handle plus the temp-table contents are sent from the caller to the called routine. The called routine may have either the dynamic INPUT TABLE-HANDLE or the static INPUT TABLE as a matching parameter.
- If the parameter is INPUT TABLE-HANDLE, a new instance of the temp-table is created along with its handle, completely separate from the caller’s table, and is populated with the contents from the caller’s table.
You can override this default behavior to allow the calling procedure and the called procedure to access the same object instance by passing the TABLE-HANDLE parameter by reference or by binding (that is, by specifying the parameter in a RUN statement using either the BY-REFERENCE or BIND option). If you specify the BIND option in the RUN statement, you must also specify the BIND option in the DEFINE PARAMETER statement.
- If the parameter is OUTPUT TABLE-HANDLE, the handle plus the definition behind the handle are sent from the caller to the called routine. The called routine may have either the dynamic OUTPUT TABLE-HANDLE or the static OUTPUT TABLE as a matching parameter.
- If the parameter is OUTPUT TABLE-HANDLE, and the handle is the Unknown value (
?), no definition is sent to the called routine.- If the parameter is OUTPUT TABLE-HANDLE, the called routine sends back the definition behind the handle along with the contents of the output temp-table. In the caller, if the original handle was the Unknown value (
?), a new instance of the temp-table is created and populated with the output contents. If the original handle is not the Unknown value (?), the caller’s existing table must match the table being received from the called routine.- If the APPEND option is used, the new data is added to the existing table’s data.
- If the parameter is INPUT-OUTPUT TABLE-HANDLE, a combination of the above occurs.
- If you call a remote procedure asynchronously (using the ASYNCHRONOUS option of the RUN statement) and pass a parameter as OUTPUT TABLE-HANDLE
temp-table-handleAPPEND, the event procedure must specify a corresponding DEFINE INPUT PARAMETER TABLE-HANDLE FORtemp-table-handleAPPEND statement, andtemp-table-handlemust be global to both the calling procedure and the event procedure.- If you define an INPUT TABLE parameter for an asynchronous event procedure with a data type that is different from the data type of the corresponding OUTPUT TABLE parameter passed from the AppServer, any failure to convert the passed value causes the event procedure to fail and Progress to display an error message on the client.
- You cannot specify a ProDataSet object or ProDataSet object handle as a parameter for an asynchronous remote procedure.
- For more information on working with asynchronous remote procedures and event procedures, see OpenEdge Application Server: Developing AppServer Applications .
- For dynamic ProDataSet object parameters:
- If the parameter is INPUT DATASET-HANDLE, the ProDataSet object definition behind the handle plus the ProDataSet object contents are sent from the caller to the called routine. The called routine may have either the dynamic INPUT DATASET-HANDLE or the static INPUT DATASET as a matching parameter.
- If the parameter is INPUT DATASET-HANDLE, a new instance of the ProDataSet object is created along with its handle, completely separate from the caller’s table, and is populated with the contents from the caller’s table.
You can override this default behavior to allow the calling procedure and the called procedure to access the same object instance by passing the DATASET-HANDLE parameter by reference or by binding (that is, by specifying the parameter in a RUN statement using either the BY-REFERENCE or BIND option). If you specify the BIND option in the RUN statement, you must also specify the BIND option in the DEFINE PARAMETER statement.
- If the parameter is OUTPUT DATASET-HANDLE, the handle plus the definition behind the handle are sent from the caller to the called routine. The called routine may have either the dynamic OUTPUT DATASET-HANDLE or the static OUTPUT DATASET as a matching parameter.
If the parameter is OUTPUT DATASET-HANDLE, and the caller’s handle is the Unknown value (
?), no definition is sent to the called routine.- If the parameter is OUTPUT DATASET-HANDLE, the called routine sends back the definition behind the handle along with the contents of the output ProDataSet object. In the caller, if the original handle is the Unknown value (
?), a new instance of the ProDataSet object is created and populated with the output contents. If the original handle is not the Unknown value (?), the caller’s existing object must match the object being received from the called routine.- If the APPEND option is used, the new data is added to the existing object’s data.
- If the parameter is INPUT-OUTPUT DATASET-HANDLE, a combination of the above occurs.
See also
DEFINE BUFFER statement, DEFINE VARIABLE statement, DELETE PROCEDURE statement, RUN statement
|
Copyright © 2005 Progress Software Corporation www.progress.com Voice: (781) 280-4000 Fax: (781) 280-4095 |